using Infrastructure;
using Infrastructure.Attribute;
using Infrastructure.Enums;
using Infrastructure.Model;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using ZR.Model.Dto;
using ZR.Model.Models;
using ZR.Service.Auth.IAuthService;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
using ZR.Common;
using Microsoft.AspNetCore.Authorization;
using ZR.Model.Dto.Auth;
using Microsoft.IdentityModel.Tokens;
using static System.Net.Mime.MediaTypeNames;
using System.Xml;
using System;
using System.Security.Cryptography.X509Certificates;
using Microsoft.AspNetCore.Identity;
using Infrastructure.Extensions;

namespace ZR.Admin.WebApi.Controllers
{
    /// <summary>
    /// 认证记录表Controller
    /// 
    /// @tableName veri_record
    /// @author admin
    /// @date 2023-03-06
    /// </summary>
    [Verify]
    [Route("auth/VeriRecord")]
    public class VeriRecordController : BaseController
    {
        /// <summary>
        /// 认证记录表接口
        /// </summary>
        private readonly IVeriRecordService _VeriRecordService;

        public VeriRecordController(IVeriRecordService VeriRecordService)
        {
            _VeriRecordService = VeriRecordService;
        }

        /// <summary>
        /// 获取百度实名认证Token
        /// </summary>
        /// <param name="phone">手机号</param>
        /// <returns></returns>
        [HttpGet("token")]
        [AllowAnonymous]
        [Log(Title = "认证记录表", BusinessType = BusinessType.GRANT)]
        public IActionResult GetAccessToken(string phone)
        {
            var response = _VeriRecordService.GetAccessToken();
            return SUCCESS(response);
        }

        /// <summary>
        /// 阿里云三要素实名认证
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        [HttpPost("auth3")]
        [AllowAnonymous]
        [Log(Title = "认证记录表", BusinessType = BusinessType.GRANT)]
        public IActionResult IdentificationByAliyun([FromBody] VeriRecordDto parm)
        {
            if (parm == null)
            {
                throw new CustomException("请求参数错误");
            }
            var modal = parm.Adapt<VeriRecord>().ToCreate(HttpContext);

            var response = _VeriRecordService.AuthenticationByAliyun(modal);

            return SUCCESS(response);
        }

        /// <summary>
        /// 查询认证记录表列表
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        [HttpGet("list")]
        [ActionPermissionFilter(Permission = "auth:verirecord:list")]
        public IActionResult QueryVeriRecord([FromQuery] VeriRecordQueryDto parm)
        {
            var response = _VeriRecordService.GetList(parm);
            return SUCCESS(response);
        }
        /// <summary>
        /// 查询认证记录表列表
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        [HttpGet("number")]
        [ActionPermissionFilter(Permission = "auth:verirecord:number")]
        [AllowAnonymous]
        public Statistics GetCount(Seach seach)
        {
            var data = _VeriRecordService.GetCount(seach);
            return data; 
        }
        /// <summary>
        /// 查询认证记录表详情
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        [HttpGet("{Id}")]
        [ActionPermissionFilter(Permission = "auth:verirecord:query")]
        public IActionResult GetVeriRecord(long Id)
        {
            var response = _VeriRecordService.GetFirst(x => x.Id == Id);
            
            return SUCCESS(response);
        }

        /// <summary>
        /// 验证是否实名制
        /// </summary>
        /// <param name="Value">手机号/身份证号</param>
        /// <returns></returns>
        [HttpGet("state")]
        [AllowAnonymous]
        public IActionResult VerifyState(string Value)
        {
            var response = _VeriRecordService.GetFirst(x => x.Phone == Value || x.IdNumber == Value);
            if (response.IsNullOrZero())
            {
                throw new CustomException("当前用户未认证！");
            }
            response._id = Convert.ToString(response.Id);
            return SUCCESS(response);
        }


        /// <summary>
        /// 添加认证记录表
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        [AllowAnonymous]
        [ActionPermissionFilter(Permission = "auth:verirecord:add")]
        [Log(Title = "认证记录表", BusinessType = BusinessType.INSERT)]
        public IActionResult AddVeriRecord([FromBody] VeriRecordDto parm)
        {
            if (parm == null)
            {
                throw new CustomException("请求参数错误");
            }
            var modal = parm.Adapt<VeriRecord>().ToCreate(HttpContext);

            var response = _VeriRecordService.AddVeriRecord(modal);

            return ToResponse(response);
        }

        /// <summary>
        /// 更新认证记录表
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("SaveVeriSign")]
        [ActionPermissionFilter(Permission = "auth:verirecord:edit")]
        [Log(Title = "认证记录表", BusinessType = BusinessType.UPDATE)]
        public IActionResult UpdateVeriRecord([FromBody] VeriRecordDto parm)
        {
            if (parm == null)
            {
                throw new CustomException("请求实体不能为空");
            }
            var modal = parm.Adapt<VeriRecord>().ToUpdate(HttpContext);

            var response = _VeriRecordService.UpdateVeriRecord(modal);

            return ToResponse(response);
        }

        /// <summary>
        /// 修改头像
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        /// <exception cref="CustomException"></exception>
        [HttpPost("avatar")]
        [AllowAnonymous]
        [Log(Title = "认证记录表", BusinessType = BusinessType.UPDATE)]
        public IActionResult UpdateAvatar([FromBody] VeriRecordDto parm)
        {
            if (parm == null)
            {
                throw new CustomException("请求实体不能为空");
            }
            var modal = parm.Adapt<VeriRecord>().ToUpdate(HttpContext);

            var response = _VeriRecordService.UpdateAvatar(modal);

            return ToResponse(response);
        }

        /// <summary>
        /// 删除认证记录表
        /// </summary>
        /// <returns></returns>
        [HttpDelete("{ids}")]
        [ActionPermissionFilter(Permission = "auth:verirecord:delete")]
        [Log(Title = "认证记录表", BusinessType = BusinessType.DELETE)]
        public IActionResult DeleteVeriRecord(string ids)
        {
            int[] idsArr = Tools.SpitIntArrary(ids);
            if (idsArr.Length <= 0) { return ToResponse(ApiResult.Error($"删除失败Id 不能为空")); }

            var response = _VeriRecordService.Delete(idsArr);

            return ToResponse(response);
        }

        /// <summary>
        /// 导出认证记录表
        /// </summary>
        /// <returns></returns>
        [Log(Title = "认证记录表", BusinessType = BusinessType.EXPORT, IsSaveResponseData = false)]
        [HttpGet("export")]
        [ActionPermissionFilter(Permission = "auth:verirecord:export")]
        public IActionResult Export([FromQuery] VeriRecordQueryDto parm)
        {
            parm.PageNum = 1;
            parm.PageSize = 100000;
            var list = _VeriRecordService.GetList(parm).Result;
            if (list == null || list.Count <= 0)
            {
                return ToResponse(ResultCode.FAIL, "没有要导出的数据");
            }
            var result = ExportExcelMini(list, "认证记录表", "认证记录表");
            return ExportExcel(result.Item2, result.Item1);
        }

        /// <summary>
        /// 获取公钥
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        /// <exception cref="CustomException"></exception>
        [Log(Title = "生成RSA密钥", BusinessType = BusinessType.EXPORT, IsSaveResponseData = false)]
        [AllowAnonymous]
        [HttpGet("publickey")]
        public IActionResult GetAccessToken([FromQuery] RsaInputDto parm)
        {
            
            #region 公有变量
            bool usePKCS8 = true;// usePKCS8=true表示是否成PKCS8格式的公私秘钥,否则乘车PKCS1格式的公私秘钥
            string filePath = Directory.GetCurrentDirectory() + "\\wwwroot\\RsaKey";
            //Console.WriteLine($"文件路径：{filePath}");// 存放pem,crt,pfx等文件的目录
            byte[] publicKey, privateKey;// 公钥和私钥
            #endregion

            if (parm.Prefix.IsNullOrEmpty())
            {
                throw new CustomException(0, "前缀不能为空");
            }
            try
            {
                publicKey = RsaHelper.ReadFromPem(Path.Combine(filePath, "rsa_" + parm.Prefix + ".pub"));
                privateKey = RsaHelper.ReadFromPem(Path.Combine(filePath, "rsa_" + parm.Prefix + ".pem"));
            }
            catch 
            {
                //通过程序生成
                RsaHelper.GenerateRsaKey(usePKCS8, out publicKey, out privateKey);
                RsaHelper.WriteToPem(publicKey, false, Path.Combine(filePath, "rsa_" + parm.Prefix + ".pub"));
                RsaHelper.WriteToPem(privateKey, true, Path.Combine(filePath, "rsa_" + parm.Prefix + ".pem"));
            }
            RsaReturnDto response = new RsaReturnDto() 
            {
                publicKey = publicKey,
                signature = RsaHelper.Sign(parm.Prefix, privateKey, "SHA512", usePKCS8)
        };
            return SUCCESS(response);
            #region 全部功能源码


            ////通过程序生成
            //RsaHelper.GenerateRsaKey(usePKCS8, out publicKey, out privateKey);
            //RsaHelper.WriteToPem(publicKey, false, Path.Combine(filePath, "rsa_" + parm.Prefix + ".pub"));
            //RsaHelper.WriteToPem(privateKey, true, Path.Combine(filePath, "rsa_" + parm.Prefix + ".pem"));
            ////保存到xml中
            //string publicKeyXml = RsaHelper.WriteToXml(publicKey, false, usePKCS8);
            //string privateKeyXml = RsaHelper.WriteToXml(privateKey, true, usePKCS8);

            ////从xml中读取
            //publicKey = RsaHelper.ReadFromXml(publicKeyXml, false, usePKCS8);
            //privateKey = RsaHelper.ReadFromXml(privateKeyXml, true, usePKCS8);

            //// Pkcs8格式公钥转换为Pkcs1格式公钥
            //publicKey = RsaHelper.Pkcs8ToPkcs1(false, publicKey);
            //// Pkcs8格式私钥转换为Pkcs1格式私钥
            //privateKey = RsaHelper.Pkcs8ToPkcs1(true, privateKey);
            //// Pkcs1格式公钥转换为Pkcs8格式公钥
            //publicKey = RsaHelper.Pkcs1ToPkcs8(false, publicKey);
            //// Pkcs1格式私钥转换为Pkcs8格式私钥
            //privateKey = RsaHelper.Pkcs1ToPkcs8(true, privateKey);

            //string encryptText = RsaHelper.RsaEncrypt(parm.Content, publicKey, usePKCS8);
            ////Console.WriteLine($"【{parm.Content}】经过【RSA】加密后：{encryptText}");

            ////string decryptText = RsaHelper.RsaDecrypt(encryptText, privateKey, usePKCS8);
            ////Console.WriteLine($"【{encryptText}】经过【RSA】解密后：{decryptText}");

            //string signature = RsaHelper.Sign(parm.Content, privateKey, "SHA512", usePKCS8);
            ////Console.WriteLine($"【{parm.Content}】经过【RSA】签名后：{signature}");

            ////bool result = RsaHelper.Verify(text, publicKey, signature, "MD5", usePKCS8);
            ////Console.WriteLine($"【{text}】的签名【{signature}】经过【RSA】验证后结果是：{result}");

            //ReaApplyDto response = new ReaApplyDto();
            //response.encryptText = encryptText;
            //response.signature = signature;
            //response.publicKey = publicKey;

            //return SUCCESS(response);
            #endregion
        }

        /// <summary>
        /// 获取解密后的内容
        /// </summary>
        /// <param name="parm"></param>
        /// <returns></returns>
        /// <exception cref="CustomException"></exception>
        [Log(Title = "解密", BusinessType = BusinessType.EXPORT, IsSaveResponseData = false)]
        [AllowAnonymous]
        [HttpPost("content")]
        public IActionResult GetContent([FromQuery] DesInputDto parm)
        {
            #region 公有变量
            bool usePKCS8 = true;// usePKCS8=true表示是否成PKCS8格式的公私秘钥,否则乘车PKCS1格式的公私秘钥
            string filePath = Directory.GetCurrentDirectory() + "\\wwwroot\\RsaKey";
            //Console.WriteLine($"文件路径：{filePath}");// 存放pem,crt,pfx等文件的目录
            byte[] publicKey, privateKey;// 公钥和私钥
            #endregion

            if (parm.Prefix.IsNullOrEmpty())
            {
                throw new CustomException(0, "前缀不能为空");
            }
            try
            {
                publicKey = RsaHelper.ReadFromPem(Path.Combine(filePath, "rsa_" + parm.Prefix + ".pub"));
                privateKey = RsaHelper.ReadFromPem(Path.Combine(filePath, "rsa_" + parm.Prefix + ".pem"));
            }
            catch
            {
                throw new CustomException(0, "您无权使用此功能");
            }

            if (!RsaHelper.Verify(parm.Prefix, publicKey, parm.Signature, "SHA512", usePKCS8))
            {
                throw new CustomException(0, "您无权使用此功能");
            }

            string decryptText = RsaHelper.RsaDecrypt(parm.Content, privateKey, usePKCS8);

            return SUCCESS(decryptText);
        }

    }
}